//
//  YCCollectionViewLayout.m
//  瀑布流
//
//  Created by 朱永超 on 2017/3/14.
//  Copyright © 2017年 zyc. All rights reserved.
//

#import "YCCollectionViewLayout.h"

@interface YCCollectionViewLayout()
//保存每一个item的attributes
@property(nonatomic , strong) NSMutableArray *attributesArr;
//用来记录每一列的最大y值
@property(nonatomic , strong) NSMutableDictionary *myDic;
@end

@implementation YCCollectionViewLayout
-(NSMutableArray *)attributesArr
{
    if (!_attributesArr) {
        _attributesArr = [NSMutableArray array];
    }
    return _attributesArr;
}
-(NSMutableDictionary *)myDic
{
    if (!_myDic) {
        _myDic = [[NSMutableDictionary alloc] init];
    }
    return _myDic;
}
-(instancetype)init
{
    if (self = [super init]) {
        self.cloumnCount = 2;
    }
    return self;
}
-(instancetype)initWithCloumnCount:(NSInteger)cloumnCount
{
    if (self = [super init]) {
        _cloumnCount = cloumnCount;
    }
    return self;
}
+(instancetype)layoutWithCloumnCount:(NSInteger)cloumnCount
{
    return [[self alloc] initWithCloumnCount:cloumnCount];
}
-(void)setCloumnSpacingWidth:(CGFloat)cloumnSpacingWidth rowSpacingHeight:(CGFloat)rowSpacingHeight borderSet:(UIEdgeInsets)borderSet
{
    self.cloumnSpacingWidth = cloumnSpacingWidth;
    self.rowSpacingHeight = rowSpacingHeight;
    self.borderSet = borderSet;
}
//准备布局
//记得先调用super的prepareLayout,一般在里面做一些必要参数的初始化.例如环形布局中的center和radius.因为每次在重新给出layout时,该方法都会被调用
-(void)prepareLayout
{
    [super prepareLayout];
    //初始化字典，有几列就有几个键值对，key为列，value为列的最大y值，初始值为上内边距
    for (int i = 0 ; i < self.cloumnCount; i++) {
        self.myDic[@(i)] = @(self.borderSet.top);
    }
    //根据collectionView获取总共有多少个item
    NSInteger allItems = [self.collectionView numberOfItemsInSection:0];
    for (int i = 0; i < allItems ; i++) {
        UICollectionViewLayoutAttributes *att = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        [self.attributesArr addObject:att];
    }
}
//（如果你的item一屏幕显示不完，那么这个方法会调用多次，当所有的item都加载完毕后，在滑动collectionView时不会调用该方法的    布局属性layoutAttributes（这里保存着她们的尺寸，位置，indexPath等等）
//返回一个布局变量的数组,在这个里面调用上面的方法生成布局变量.这里实例化UICollectionViewLayoutAttributes的时候一定不能使用alloc,init
//返回rect范围内item的attributes
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    return self.attributesArr;
}
//计算collectionView的contentSize
-(CGSize)collectionViewContentSize
{
    //遍历字典，找出最长的那一列
    //遍历记录Y值的字典  如果maxY小于当前遍历的obj，就把大的值的key赋给maxY   返回字典中最大值的value
    __block NSNumber *maxY = @0;
    [self.myDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        if ([self.myDic[maxY] floatValue] < [obj floatValue]) {
            maxY = key;
        }
    }];
    //collectionView的contentSize.height就等于最长列的最大y值+下内边距
    
    return CGSizeMake(0, [self.myDic[maxY] floatValue] + self.borderSet.bottom);
}
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    //根据indexPath获取item的attributes
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    //获取collectionView的宽度
    CGFloat collectionViewWidth = self.collectionView.frame.size.width;
    //item的宽度= (collectionView的宽度 - 内边距 - 列间距) / 列数
    CGFloat itemWidth = (collectionViewWidth - self.borderSet.left - self.borderSet.right - (self.cloumnCount - 1)*self.cloumnSpacingWidth)/self.cloumnCount;
    CGFloat itemHeight = 0;
    //获取item的高度 从外界计算得到
    if ([self.delegate respondsToSelector:@selector(allocCollectionViewLayout:itemHeightForWidth:with:)]) {
        itemHeight = [self.delegate allocCollectionViewLayout:self itemHeightForWidth:itemWidth with:indexPath];
    }
    //找出最短的一列
    __block NSNumber *minY = @0;
    [self.myDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        if ([self.myDic[minY] floatValue] > [obj floatValue]) {
            minY = key;
        }
    }];
    //根据最短列的列数计算item的x值
    CGFloat itemX = self.borderSet.left + (self.cloumnSpacingWidth + itemWidth)*minY.integerValue;
    //item的y值 = 最短列的最大y值 + 行间距
    CGFloat itemY = [self.myDic[minY] floatValue] + self.borderSet.bottom;
    //设置attributes的frame
    attributes.frame = CGRectMake(itemX, itemY, itemWidth, itemHeight);
    //更新字典中的最大y值
    self.myDic[minY] = @(CGRectGetMaxY(attributes.frame));
    
    return attributes;
}
@end
